/*
Copyright (C) 2013 Matthew Netsch

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
*/

#include "pass.h"
#define _CRT_SECURE_NO_WARNINGS
#include <Windows.h>

namespace PassMan
{

    /*******************************************************
     * IPass
     *******************************************************/

    /**
    *   @brief 
    *       Destructor for IPass
    *   @return 
    *       N/A
    */ 
    IPass::~IPass()
    {
    }

    /*******************************************************
     * Pass
     *******************************************************/
     
    /**
    *   @brief 
    *       Constructor for password
    *   @return 
    *       N/A
    */
    Pass::Pass(
        const char *name)   ///< Name of password
        : name(NULL),
          value(NULL)
    {
        setName(name);
    }

    /**
    *   @brief 
    *       Copy constructor
    *   @return 
    *       N/A
    */
    Pass::Pass(
        Pass *pass) ///< Password to copy
        : name(NULL),
          value(NULL)
    {
        //Init pass
        copy(pass);
    }

    /**
    *   @brief 
    *       Destructor
    *   @return 
    *       N/A
    */
    Pass::~Pass()
    {
        if (name)
        {
            free(name);
        }

        if (value)
        {
            free(value);
        }
    }

    /**
    *   @brief 
    *       Gets the name of this password
    *   @return 
    *       Name
    */
    char* 
    Pass::getName()
    {
        return name;
    }

    /**
    *   @brief 
    *       Gets the value of this password
    *   @return 
    *       Value
    */
    char* 
    Pass::getValue()
    {
        return value;
    }

    /**
    *   @brief 
    *       Gets the size needed to store name
    *   @return 
    *       Size of name including null terminator
    */
    int 
    Pass::getNameSize()
    {
        if (name)
        {
            return strlen(name) + 1;
        }

        //Always have room for null terminator
        return 1;
    }

    /**
    *   @brief 
    *       Gets the value to store password
    *   @return 
    *       Size of value including null terminator
    */
    int
    Pass::getValueSize()
    {
        if (value)
        {
            return strlen(value) + 1;
        }

        //Always have room for null terminator
        return 1;
    }

    /**
    *   @brief 
    *       Gets the name of this password
    *   @return 
    *       true if success
    */
    bool
    Pass::getName(
        char   *name,   ///< Place where name will be returned
        int     size)   ///< Size of name buffer
    {
        //Null terminate just in case we can't copy over
        if (name && (size > 0))
        {
            name[0] = '\0';
        }

        if (Pass::name && name && ((unsigned int)size > strlen(Pass::name)))
        {
            strcpy(name, Pass::name);
            return true;
        }

        return false;
    }

    /**
    *   @brief 
    *       Gets the value of this password
    *   @return 
    *       true if success
    */
    bool
    Pass::getValue(
        char    *value, ///< Place where value will be returned
        int      size)  ///< Size of value buffer
    {
        //Null terminate just in case we can't copy over
        if (value && (size > 0))
        {
            value[0] = '\0';
        }

        if (Pass::value && value && ((unsigned int)size > strlen(Pass::value)))
        {
            strcpy(value, Pass::value);
            return true;
        }

        return false;
    }

    /**
    *   @brief 
    *       Sets the value of this password
    *   @return 
    *       N/A
    */
    void 
    Pass::setValue(
        const char *value)  ///< New password value
    {
        //Free old value
        if (Pass::value)
        {
            free(Pass::value);
            Pass::value = NULL;
        }

        if (!value)
        {
            return;
        }

        //Create a new value and init it with new value
        Pass::value = (char*)malloc(sizeof(char) * (strlen(value) + 1));

        strcpy(Pass::value, value);
    }

    /**
    *   @brief 
    *       Sets the name of this password
    *   @return 
    *       N/A
    */
    void
    Pass::setName(
        const char *name)   ///< New password name
    {
        if (Pass::name)
        {
            free(Pass::name);
            Pass::name = NULL;
        }
        
        if (!name)
        {
            return;
        }

        //Create a new name and init it with new name
        Pass::name = (char*)malloc(sizeof(char) * (strlen(name) + 1));
        strcpy(Pass::name, name);
    }

    /**
    *   @brief 
    *       Copies pass state to this pass
    *   @return 
    *       N/A
    */
    void 
    Pass::copy(
        Pass *pass) ///< Pass to copy state from
    {
        if (!pass)
        {
            return;
        }

        //Copy pass
        setName(pass->getName());
        setValue(pass->getValue());
    }

}